<?php

class Dom_Html extends Dom {

    public function __construct($version = NULL, $encoding = NULL) {
        parent::__construct($version, $encoding);
    }

    /*  loadTemplate(string $fileName)      :   Loads the desired file into the current document
     *
     *  @access public
     *  @param  string  $fileName       -   Location of the file to include into the document
     *  @return bool                    -   Returns true or false if file was loaded
     */
    public function loadTemplate($fileName) {
        return self::loadHTMLFile($fileName);
    }

    /*  loadExternalTemplate(string $url)      :   Loads the desired external doc from url into the current document
     *
     *  @access public
     *  @param  string  $url       -   Location of the external file to include into the document
     *  @return bool                    -   Returns true or false if file was loaded
     */
    public function loadExternalTemplate($url) {
        $html = file_get_contents($url);
        return self::loadHTML($html);
    }

    /*  getBodyElement()                    :   Grabs the <body> element
     *
     *  @access public
     *  @return DOMNode $node       -   Returns node of element
     */
    public function getBodyElement() {
        if(($node = self::getTagFirst("body")) === FALSE) {
            $node   =   self::createElement("body");

            self::appendChild($node);
        }

        return $node; 
    }

    /*  getHeadElement()                    :   Grabs the <head> element
     *
     *  @access public
     *  @return DOMNode $node       -   Returns the node of the element
     */
    public function getHeadElement() {
        if(($node = self::getTagFirst("head")) === FALSE) {
            $node   =   self::createElement("head");
            $body   =   self::getBodyElement();

            $body->ownerDocument->insertBefore($node, $body);
        }

        return $node;
    }
        
    /*
     *  setTitle(string $title)             :   Set the title on the current document
     *
     *  @access public
     *  @param  string  $title          -   The title that is being set
     */
    public function setTitle($title, $overwrite = FALSE) {
        if(($node = self::getTagFirst("title")) === FALSE) {
            $node   =   self::createElement("title", $title);
            $head   =   self::getHeadElement();

            $head->appendChild($node);
        } elseif(isset($overwrite) && $overwrite === TRUE) {
            $node->nodeValue    =   $title;
        } else {
            $node->nodeValue    .=   $title;
        }
    }

    /*  addStylesheet(string $fileName)     :   Adds specified stylesheet to the document
     *
     *  @access public
     *  @param  string  $fileName       -   Path to the filename to include into document
     *  @return bool                    -   Returns false on failure 
     */
    public function addStylesheet($fileName) {
        $config     =   control::getConfigs();
        $head       =   self::getHeadElement();
        $node       =   self::createElement("link");

        $head->appendChild($node);
        $node->setAttribute("rel", "stylesheet");
        $node->setAttribute("href", $fileName);
    }

    /*  addMeta(array $attributes, [string $value]) :   Adds a meta tag to the <head> element of the document
     *
     *  @access public
     *  @param  array   $attributes     -   Array of attributes to add to the meta tag
     *  @param  string  $value          -   Value to add to the meta tag
     */
    public function addMeta($attributes, $value = NULL) {
        if(is_array($attributes) && !empty($attributes)) {
            $head   =   self::getHeadElement();
            $node   =   self::createElement("meta", $value);
            $head->appendChild($node);

            if(self::setAttributes($node, $attributes) === FALSE) {
                throw new Exception("Failed to set attributes to meta tag");
            }
        } else {
            throw new Exception("Meta tags attempted to be created without any attributes");
        }
    }

    /*  addJavascript(string $data, [DOMNode $targetNode])         :   Adds the javascript data to the document
     *
     *  @access public
     *  @param  string  $data       -   Javascript to include into the document
     *  @param  DOMNode $targetNode -   Node to append javascript into
     */
    public function addJavascript($data, $targetNode = NULL) {
        if(!isset($targetNode) || empty($targeNode)) {
            $targetNode =   self::getHeadElement();
        }

        $node   =   self::createElement("script");
        $node->setAttribute("type", "text/javascript");
        $node->setAttribute("src", $data);
        $targetNode->appendChild($node);
    }
	
	/* redirect(string $url, int $time) : Created and returns a js redirect
	 *
	 * @access public
	 * @param  string $url  - url to redirect to
	 * @param  int $time    - Deprecated, we'll leave it for backwards compatibility
	 */
	public function redirect($url, $time = NULL) {
		if(filter_var($url, FILTER_VALIDATE_URL) !== FALSE) {
            $script =   self::createElement("script", "window.location ='$url'");
            $head   =   self::getHeadElement();
            $head->appendChild($script);
			$script->setAttribute("type", "text/javascript");
			return TRUE;
		} else {
			return FALSE;
		}
	}

    /*  a(string $name, string $href, [array $attribs])
     *
     *  @access public
     *  @param  string  $name       -   A tag's nodeValue
     *  @param  string  $href       -   The href to be set on the A tag
     *  @param  array   $attribs    -   Additional attributes to apply to the tag
     *  @return node    $tag        -   The node of the tag
     */
    public function a($name, $href, $attribs = NULL) {
        $tag    =   self::createElement("a", $name);
        $tag->setAttribute("href", $href);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function b($string, $attribs = NULL) {
        $tag    =   self::createElement("b", $string);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function base($url) {
        $head   =   self::getHeadElement();
        $tag    =   self::createElement("base");
        $tag->setAttribute("href", $url);
        $head->appendChild($tag);
    }

    public function br($attribs = NULL) {
        $tag    =   self::createElement("br");
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function button($string, $attribs = NULL) {
        $tag    =   self::createElement("button", $string);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function div($data = NULL, $attribs = NULL) {
        $tag    =   self::createElement("div", $data);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function form($action, $attribs = NULL) {
        if(isset($attribs) && is_array($attribs)) {
            if(!isset($attribs['method'])) {
                $method =   "POST";
            } else {
                $method =   $attribs['method'];

                unset($attribs['method']);
            }
        }

        $tag    =   self::createElement("form");
        $tag->setAttribute("method", $method);
        unset($attribs['method']);

        self::setAttributes($tag, $attribs);
        return $tag;
    }

    public function i($string, $attribs = NULL) {
        $tag    =   self::createElement("i", $string);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function img($src, $attribs = NULL) {
        $tag    =   self::createElement("img");
        $tag->setAttribute("src", $src);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function input($name, $type, $attribs = NULL) {
        $tag    =   self::createElement("input");
        $tag->setAttribute("name", $name);
        $tag->setAttribute("type", $type);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function p($data, $attribs = NULL) {
        $tag    =   self::createElement("p", $data);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function textarea($string, $cols, $rows, $attribs = NULL) {
        $tag    =   self::createElement("textarea", $string);

        $tag->setAttribute("cols", $cols);
        $tag->setAttribute("rows", $rows);
        self::setAttributes($tag, $attribs);

        return $tag;
    }

    public function td($data, array $attribs = NULL) {
    	$tag	=	self::createElement("td");
    	
    	self::appendString($tag, $data);
    	self::setAttributes($tag, $attribs);
    	
    	return $tag;
    }
    
    public function span($data, array $attribs = NULL) {
    	$tag	=	self::createElement("span", $data);
    	
    	self::appendString($tag, $data);
    	self::setAttributes($tag, $attribs);
    	
    	return $tag;
    }
    
	public function select($name, array $options, $attribs = NULL) {
        $tag    =   self::createElement("select", $name);
        self::setAttributes($tag, $attribs);

		foreach($options as $key => $o) {
			if(isset($o['label'])) {
                $tag->appendChild($opt[$key] = self::createElement("option", $o['label']));
				if(isset($o['value'])) {
					$opt[$key]->setAttribute("value", $o['value']);
				} else {
					$opt[$key]->setAttribute("value", $o['label']);
				}
			} else {
				throw new Exception('Missing associative key in options array, required : "label", optional : "value"');
			}
		}
		
		return $tag;
	}

    public function __destruct() {
        print self::saveHTML();
    }
}
?>